home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-25 | 13.1 KB | 264 lines | [TEXT/MPS ] |
- /*[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]*/
- /* UMenuSetup.p */
- /* Copyright © 1984-1990 Apple Computer Inc. All rights reserved. */
-
- /*
- T H E O R Y O F O P E R A T I O N
-
- This unit provides two features: It implements a command numbering
- system that is independent of menu/item placement, and implements a
- framework for optimizing menu setups.
-
- The command numbering system works by assigning commands a unique
- integer number, and providing a mechanism for mapping command numbers
- to menu/item pairs. A set of routines are provide to manipulate
- commands via their command number rather than their menu and item
- numbers.
-
- Each command can be assigned an integer command number from 1 to
- 32767. To associate a command number with a menu item, menu resources
- are defined with the 'cmnu' resource type--not the 'MENU' type. The
- 'cmnu' type is just like the 'MENU' type, with an additional command
- number field for each menu item. The PostRez Tool converts the
- 'cmnu' output of Rez into equivalent 'MENU' resources and one 'mntb'
- resource. The 'mntb' resource maps command numbers to menu/item pairs.
-
- The items of some menus cannot be determined until run-time. The font
- menu is an example. In such cases, no command number is assigned by
- you. Instead, the command number is equal to -(256 * menu + item).
-
- The procedure CmdToMenuItem converts a command number to a menu id
- and item number by the following method:
-
- - If the command number is positive, the command table is searched
- for the number. If it is found, CmdToMenuItem returns the corre-
- sponding menu id and item number. Otherwise the menu and item are
- zero.
-
- - If the command number is negative, the menu number is the upper eight
- bits, and the item number the lower eight bits, of the absolute value
- of the command number. (This implies that menu id's must be <= 127
- and item numbers must be <= 255.)
-
- The function CmdFromMenuItem converts menu/items to command numbers by
- the following method:
-
- - If the item number is positive, the command table is search for the
- given menu/item pair. If found, the corresponding command number is
- returned. If not found, the number returned is equal to
- -(256 * menu + item).
-
- - If the item number is negative, the number returned is equal to
- -item number.
-
- Note that CmdToMenuItem and CmdFromMenuItem work regardless of whether
- the command is actually installed in the menu bar. MacApp takes
- advantage of this feature by having a set of generic "buzz" commands,
- whose primary use is to set the name of the Undo command (e.g. 'Undo
- Drawing').
-
- The second feature of this unit is to optimize menu setups (changing
- the appearance of menus and items). Normally, each call to CheckItem,
- SetItemStyle and SetCmdIcon in turn calls CalcMenuSize because the width
- or height of the menu may have changed. If menu setups are done all at
- one time, then CalcMenuSize can be deferred until the end of the setup
- process. The procedure PerformMenuSetup implements this mechanism. It
- relies on the fact that menu setups are done all at once, and that you
- will call SetCmdName, SetItemStyle and SetCmdIcon instead of SetItem,
- SetItemStyle and SetCmdIcon. It works only for menus whose id is from
- 1 to mLastMenu. Menus with IDs greater than mLastMenu are not affected
- by this scheme.
-
- PerformMenuSetup accepts one parameter, a procedure which actually
- implements the menu appearance changes. SetupMenus performs the
- following steps:
-
- - Before calling your menu setup procedure, StartupMenuSetup is called.
- It disables all menus and items, remembers the current
- menu proc and enabled flags of each menu, and sets the MenuProc of
- each menu to gHNullMenuProc, thereby disabling CalcMenuSize.
- - Your procedure is called. It in turn calls SetCmdName,
- SetCmdStyle, SetCmdIcon, Enable, EnableCheck, or a
- Toolbox routine (provided it isn't SetItem, SetItemStyle or
- SetCmdIcon).
- - Menus with at least one enabled item are enabled, CalcMenuSize is
- called for those menus that need it, each menu's menuproc is restored,
- and DrawMenuBar is called if the enabled state of any menu changed.
- */
-
- #ifndef __UMenuSetup__
- #define __UMenuSetup__ 0
- #endif
- #if ! __UMenuSetup__
- #define __UMenuSetup__ 1
-
- /* • Required for this unit's interface. Auto-Include them */
- #ifndef __TYPES__
- #include "Types.h"
- #endif
- #ifndef __MENUS__
- #include "Menus.h"
- #endif
-
- const unsigned long kMNTBbyCmdNumber = 'mntb'; /* menu command number table type */
- const short kIDMNTBbyCmdNumber = 128; /* menu command number table ID */
-
- const short mFirstMenu = 1; /* MacApp manages menu titles
- mFirstMenu..mLastMenu generically */
- const short mApple = mFirstMenu; /* MacApp does not disable any commands in
- this menu */
- const short mFile = mApple + 1; /* Default ID of the File menu */
- const short mEdit = mFile + 1; /* Default ID of the Edit menu */
-
- const short mDebug = 900; /* read in if debugging is turned on; number
- corresponds with debugging command numbers
- */
- const short mLastMenu = 63; /* MacApp disables menu titles
- mFile..mLastMenu generically */
-
- typedef short CmdNumber; /* CmdNumbers tell MacApp what verb is
- intended after mapping from menu/item. */
-
- extern pascal Boolean gMenusAreSetup; /* set FALSE before every event; set TRUE by
- SetupTheMenus, which is called at Idle
- Begin; if your DoIdle changes the target
- or makes other changes that would alter
- the appearance of menus, you must set
- gMenusAreSetup to FALSE there. */
- extern pascal Boolean gRedrawMenuBar; /* if TRUE, then DrawMenuBar will be called
- by TApplication.SetupTheMenus. If you have
- menus that are not handled by MacApp, your
- implementation(s) of DoSetupMenus can set
- this to TRUE to force the menu bar to be
- redrawn. */
- #if qDebug
- extern pascal Boolean gTraceSetupMenus;
- #endif
-
- /* The following routines all recognize command numbers of the form -(256 * menu + item) and
- -(256 * menu). The former is used when there is no command number; the latter to
- enable/disable a whole menu (rare) */
-
- extern pascal Boolean CmdEnabled(CmdNumber cmd);
- /* Returns true if the given cmd is currently enabled. */
-
- extern pascal CmdNumber CmdFromMenuItem(short menu, short item);
- /* Returns the command number for the given menu ID and item number. If the item number is
- positive, the command table is search for the given menu/item pair. If found, the
- corresponding command number is returned. If not found, the number returned is equal to
- -(256 * menu + item). If the item number is negative, the number returned is equal to -item
- number. */
-
- extern pascal void CmdToMenuItem(CmdNumber aCmd, short *menu, short *item);
- /* CmdToMenuItem returns the menu ID and item number of the given command. If aCmd is
- positive, the command table is searched for aCmd. If it is found, CmdToMenuItem returns the
- corresponding menu ID and item number. Otherwise menu and item are set to zero. If aCmd is
- negative, the menu number is the upper eight bits, and the item number the lower eight
- bits, of the absolute value of aCmd. (This implies that menu id's must be <= 127 and item
- numbers must be <= 255.) */
-
- extern pascal MenuHandle CmdToComponents(CmdNumber cmd, short *menuNo, short *itemNo);
- /* CmdToComponents returns the menu ID and item number of the given command. as well as
- the MenuHandle if the cmd exists. Otherwise it returns nil. */
-
- extern pascal void CmdToName(CmdNumber aCmd, StringPtr menuText);
- /* Return the text of the menu item for the given command. */
-
- extern pascal void EachMenuDo(pascal void (*DoToMenu)(MenuHandle aMenuHandle, Boolean isHierarchical
- , void *DoToMenu_StaticLink), void *DoToMenu_StaticLink, Boolean includeHierarchical);
- /* Sequences thru each menu in menu bar with ID in [0..mLastMenu], calling DoToMenu for each
- menu. Handles mDebug as a special case. */
-
- extern pascal void Enable(CmdNumber aCmd, Boolean canDo);
- /* Enable or disable a command */
-
- extern pascal void EnableCheck(CmdNumber aCmd, Boolean canDo, Boolean checkIt);
- /* Enable/Disable and check/uncheck a command */
-
- extern pascal MenuHandle GetResMenu(short menuResID);
- /* Utility that just does GetResource('MENU', resourceID), so that it works for menus not
- currently in the menu bar. (You cannot call GetMenu more than once for the same menu, so
- you can use this (or MAGetMenu which is preferred) instead.) */
-
- extern pascal void InitUMenuSetup(void);
- /* Initializes this unit, and must be called before using any other part of this unit. Loads
- the command table and sets up the null menu proc. */
-
- extern pascal Handle MAGetNewMBar(short menuRsrcID);
- /* Equivalent to the Menu Manager's GetNewMBar except it explicitly sets the menu bar's
- colors.*/
-
- extern pascal void MAInsertMenu(MenuHandle theMenu, short beforeID);
- /* Equivalent to the Menu Manager's InsertMenu with the addition that the MAInsertMenu looks
- for an 'mctb' resource whose id is the menu's id, and if it is present applies the 'mctb'
- to the menu.*/
-
- extern pascal MenuHandle MAGetMenu(short menuNo);
- /* Not quite equivalent to GetMenu because it doesn't load the menuDefProc or color tabl
- e yet.
- It does, however, let you get the menuhandle without calling GetMenu more than o
- nce. It tries
- the menubar first and then calls GetResMenu if necessary. */
-
- extern pascal void NeedCalcMenuSize(MenuHandle aMenuHandle);
- /* This procedure is called as part of the menu setup process and indicates that the given
- menu needs CalcMenuSize. You must explicitly call this if you use change a menu by means
- other than those supplied in this unit (e.g. you insert or delete items from a menu).
- Failure to do so will result in improperly sized menus. */
-
- extern pascal void SetCmdIcon(CmdNumber aCmd, short menuIcon);
- /* You should call this (instead of the Toolbox's SetCmdIcon) for menus that are in the
- range
- [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's size
- needs to be recomputed. */
-
- extern pascal void SetCmdName(CmdNumber aCmd, StringPtr menuText);
- /* You should call this (instead of the Toolbox's SetItem) for menus that are in the range
- [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's size
- needs to be recomputed. */
-
- extern pascal void SetIndCmdName(CmdNumber aCmd, short rsrcID, short strIndex);
- /* Does a GetIndString with the rsrcID & strIndex; and then a SetCmdName. */
-
- extern pascal void SetMenuState(CmdNumber aCmd, short rsrcID, short falseBuzzItem, short
- trueBuzzItem, Boolean stateVariable);
- /* IF stateVariable THEN
- SetIndCmdName(aCmd, rsrcID, trueBuzzItem)
- ELSE
- SetIndCmdName(aCmd, rsrcID, falseBuzzItem);
- */
-
- extern pascal void SetStyle(CmdNumber aCmd, unsigned short aStyle);
- /* You should call this (instead of the Toolbox's SetItemStyle) for menus that are in the
- range [1..mLastMenu]. In addition to changing the menu this tells MacApp that the menu's
- size needs to be recomputed. */
-
- extern pascal void PerformMenuSetup(pascal void (*TheMenuSetterUpper)(void *
- TheMenuSetterUpper_StaticLink), void *TheMenuSetterUpper_StaticLink);
- /* Routine that perfoms the menu setup. */
-
- extern pascal void InvalidateMenus(void);
- /* Invalidate all the items on all the menus. Just like invalidation for windows it doesn't
- immediately change the visual appearance when you invalidate, it just means they are invalid
- and should be "setup" before showing them to the user again. */
-
- extern pascal void ValidateMenus(void);
- /* Validate all the items on all the menus. Just like Validation for windows it doesn't
- immediately change the visual appearance when you Validate, it just means they don't need
- to be changed before showing them to the user again. */
-
- extern pascal Boolean MenusHavePendingUpdate(void);
- /* TRUE if the menus are invalid and should be "setup" before showing them to the user. */
-
- extern pascal void InvalidateMenuBar(void);
- /* Invalidate the menu bar. It should be redrawn again. */
-
- extern pascal void ValidateMenuBar(void);
- /* Validate the menu bar. It doesn't need redrawing, its just fine thank you. */
-
- extern pascal Boolean MenuBarHasPendingUpdate(void);
- /* TRUE if the menu bar is invalid and should be redrawn. */
-
- #endif
-
-